/**
    @project {
        "templateId": "org.helgoboss.custom",
        "version": "0.1-SNAPSHOT",
        "dependencies": [
            "org.scala-lang:scala-library:2.9.0-1",
            "org.helgoboss:commandlet-api:0.1-SNAPSHOT"
        ]
    }
*/

package org.helgoboss.commandlet_convenience

import java.io.{PrintWriter, BufferedReader, InputStreamReader}
import scala.io.Source
import org.helgoboss.commandlet._
import java.io.File

object Implicits extends Implicits

trait Implicits {
    implicit def executionContextToIoSupport(ec: ExecutionContext) = new IoSupport(ec)
    implicit def executionContextToFileHandlingSupport(ec: ExecutionContext) = new FileHandlingSupport(ec)
    implicit def executionContextToErrorHandlingSupport(ec: ExecutionContext) = new ErrorHandlingSupport(ec)
    implicit def argumentsToSimpleOptionParsingSupport(args: Seq[String]) = new SimpleOptionParsingSupport(args)
}

case class Options(qualified: Map[String, String], positional: Seq[String])

class SimpleOptionParsingSupport(args: Seq[String]) {
    
    lazy val options = {
        val tmpPairsMap = new collection.mutable.HashMap[String, String]
        val tmpPositionalBuffer = new collection.mutable.ListBuffer[String]
        var currentOptionKey: Option[String] = None
        args.foreach { arg =>
            val trimmedArg = arg.trim
            def isOptionKey = trimmedArg.startsWith("--")
            
            currentOptionKey match {
                case Some(k) =>
                    if (!isOptionKey) {
                        tmpPairsMap(k) = arg
                        currentOptionKey = None
                    }

                case None =>
                    if (isOptionKey) 
                        currentOptionKey = Some(trimmedArg.substring(2))
                    else
                        tmpPositionalBuffer += trimmedArg
            }
                    
        }
        Options(qualified = tmpPairsMap.toMap, positional = tmpPositionalBuffer.toList)
    }
}

class ErrorHandlingSupport(ec: ExecutionContext) {
    def fail(message: String): Nothing = {
        new IoSupport(ec).writer.println(message)
        error(message)
    }
}

class FileHandlingSupport(ec: ExecutionContext) {
    def resolveFile(path: String): File = resolveFile(new File(path))

    def resolveFile(file: File): File = {
        if (file.isAbsolute)
            file
        else
            new File(ec.workingDirectory, file.getPath)
    }
}

class IoSupport(ec: ExecutionContext) {
    lazy val writer = new PrintWriter(ec.outputStream, true)
    lazy val reader = new BufferedReader(new InputStreamReader(ec.inputStream))
    lazy val source = Source.fromInputStream(ec.inputStream)
}